//*****************************************************************************
//
//! \file MPL115A1.c
//! \brief Control for MPL115A1 sensor.
//! \version 1.0.0.0
//! \date 12/31/2012
//! \author Nemon
//! \copy
//!
//! Copyright (c)  2011, CooCox
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//!     * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//!     * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution.
//!     * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************

#include "xhw_ints.h"
#include "xhw_nvic.h"
#include "xhw_memmap.h"
#include "xhw_types.h"
#include "xdebug.h"
#include "xcore.h"
#include "xsysctl.h"
#include "xhw_sysctl.h"
#include "xhw_gpio.h"
#include "xgpio.h"
#include "xhw_SPI.h"
#include "xSPI.h"

#include "xhw_ints.h"
#include "cookie.h"

#include "MPL115A1.h"
//#include "MPL115A_general_algorithm.h"


#define MPL115A1_SPI_ConfigSet \
	                         SPI_FORMAT_MODE_0 | SPI_DATA_WIDTH8 | \
	                         SPI_MSB_FIRST | SPI_MODE_MASTER

#define MPL115A2_CMD_COEFICNTS  {0x88,0x8a,0x8c,0x8e,0x90,0x92,0x94,0x96}
#define MPL115A2_CMD_CONVERSION 0x24
#define MPL115A2_CMD_RESULT     {0x80,0x82,0x84,0x86}

//*****************************************************************************
//
//! \brief ONLY FOR driver to calculate Pressure.
//!
//! calculate Pressure. from Freescale Note and write by: John B. Young
//!
//! \return int[16,4] the pressure value
//
//*****************************************************************************
static signed short MPL115A_calculatePressure(unsigned short Padc, unsigned short Tadc,
                signed short a0, signed short b1, signed short b2, signed short c12)
{
        signed long Pressure;
        signed long c12x2, a1, a1x1, y1, a2x2, PComp;
        Padc >>= 6;
        Tadc >>= 6;
        c12x2 = (((signed long)c12) * Tadc) >> 11;
        a1    = (signed long)b1 + c12x2;
        a1x1  = a1 * Padc;
        y1    = (((signed long)a0) << 10) + a1x1;
        a2x2  = (((signed long)b2) * Tadc) >> 1;
        PComp = (y1 + a2x2) >> 9;
        //return (signed short)PComp;
        Pressure = ((((signed long)PComp) * 1041) >> 14) + 800;
        return (unsigned short)Pressure;
}


//*****************************************************************************
//
//! \brief make sensor MPL115A1 init.
//!
//! make sensor MPL115A1 init.
//!
//! \return None
//
//*****************************************************************************
void MPL115A1Init(void)
{
	//xSysCtlClockSet(8000000, xSYSCTL_XTAL_12MHZ | xSYSCTL_OSC_MAIN);
	xSysCtlPeripheralEnable(MPL115A1_SYSCTL_PERIPH_SPI);

    xSPinTypeSPI(MPL115A1_SPI_CLK_, MPL115A1_SPI_CLK);
    xSPinTypeSPI(MPL115A1_SPI_MOSI_, MPL115A1_SPI_MOSI);
    xSPinTypeSPI(MPL115A1_SPI_MISO_, MPL115A1_SPI_MISO);
    xSPinTypeSPI(MPL115A1_SPI_CS_, MPL115A1_SPI_CS);

#ifdef MPL115A1_SPI_SHDN
        xSysCtlPeripheralEnable(xGPIOSPinToPeripheralId(MPL115A1_SPI_SHDN));
        xGPIOSPinWrite(MPL115A1_SPI_SHDN, 1);//~SHDN
#endif

	xSPIConfigSet(MPL115A1_SPI_BASE, MPL115A1_SPI_CLOCK, MPL115A1_SPI_ConfigSet);

	xSPISSSet(MPL115A1_SPI_BASE, xSPI_SS_SOFTWARE, xSPI_SS0);

}

//*****************************************************************************
//
//! \brief get current pressure value.
//!
//! get current pressure value.
//!
//! \return the pressure float value
//
//*****************************************************************************
signed short MPL115A1GetPressure()
{
	unsigned char ucCommandVar[8]=MPL115A2_CMD_COEFICNTS;
	unsigned char ucVar[8];
	unsigned char ucCommandRaw[4]=MPL115A2_CMD_RESULT;
	unsigned char ucRaw[4];

    signed short iResult,i;

#ifdef MPL115A1_SPI_SHDN
	xGPIOSPinWrite(MPL115A1_SPI_SHDN, MPL115A1_SPI_ENABLE);
	xSysCtlDelay(MPL115A1_SPI_1ms*5);
#endif
	/* read COEFFICIENTS */
	for(i = 0; i < 8; i++)
    {
    	xSPISingleDataReadWrite(MPL115A1_SPI_BASE, ucCommandVar[i]);
    	ucVar[i] = xSPISingleDataReadWrite(MPL115A1_SPI_BASE, 0x00);
    }
    xSPISingleDataReadWrite(MPL115A1_SPI_BASE, 0x00);
	xSysCtlDelay(MPL115A1_SPI_1ms*3);

	xSPISSSet(MPL115A1_SPI_BASE, xSPI_SS_SOFTWARE, xSPI_SS0);
	/* Command to SPI Start Conversion */
	xSPISingleDataReadWrite(MPL115A1_SPI_BASE, MPL115A2_CMD_CONVERSION);
	xSPISingleDataReadWrite(MPL115A1_SPI_BASE, 0x00);

	xSPISSSet(MPL115A1_SPI_BASE, xSPI_SS_SOFTWARE, xSPI_SS0);
	/*   wait 3ms */
	//xSysCtlDelay(MPL115A1_SPI_1ms*3);
	/*   wait 0.4s */
	xSysCtlDelay(MPL115A1_SPI_1ms*400);

	/*   SPI Read Results */
    for(i = 0; i < 4; i++)
    {
    	xSPISingleDataReadWrite(MPL115A1_SPI_BASE, ucCommandRaw[i]);
    	ucRaw[i] = xSPISingleDataReadWrite(MPL115A1_SPI_BASE, 0x00);
    	xSysCtlDelay(MPL115A1_SPI_1ms*3);
    }
    xSPISingleDataReadWrite(MPL115A1_SPI_BASE, 0x00);

    xSPISSSet(MPL115A1_SPI_BASE, xSPI_SS_SOFTWARE, xSPI_SS0);

#ifdef MPL115A1_SPI_SHDN
	xGPIOSPinWrite(MPL115A1_SPI_SHDN, MPL115A1_SPI_DISABLE);
#endif

	iResult= MPL115A_calculatePressure(
    		(((unsigned short)ucRaw[0] << 8) | ((unsigned short)ucRaw[1])) ,
    		(((unsigned short)ucRaw[2] << 8) | ((unsigned short)ucRaw[3])) ,
    		(((unsigned short)ucVar[0] << 8) | ((unsigned short)ucVar[1])) ,
    		(((unsigned short)ucVar[2] << 8) | ((unsigned short)ucVar[3])) ,
    		(((unsigned short)ucVar[4] << 8) | ((unsigned short)ucVar[5])) ,
    		(((unsigned short)ucVar[6] << 8) | ((unsigned short)ucVar[7]))
    );
	return iResult;
}

